/**
 @file sys_tmg_datapath.h

 @date 2023-02-11

 @version v0.1

 The file define APIs and types use in sys layer
*/
#ifndef _SYS_TMG_DATAPATH_H
#define _SYS_TMG_DATAPATH_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_const.h"
#include "ctc_vector.h"
#include "sys_usw_dmps.h"
#include "sys_usw_common.h"
#include "sys_usw_datapath.h"
#include "sys_tmg_mac.h"

/***************************************************************
 *
 * Defines and Macros
 *
 ***************************************************************/
#define SYS_TMG_USELESS_ID8   0xff
#define SYS_TMG_USELESS_ID16  0xffff
#define SYS_TMG_USELESS_ID32  0xffffffff

#define SYS_TMG_DP_NUM                               2
#define SYS_TMG_MAX_SERDES_NUM_PER_DP                40
#define SYS_TMG_MAX_SERDES_NUM_NW                    80
#define SYS_TMG_MAX_SERDES_NUM                       84
#define SYS_TMG_MAX_MAC_NUM_PER_DP                   SYS_TMG_MAX_SERDES_NUM_PER_DP
#define SYS_TMG_MAX_MAC_NUM_NW                       SYS_TMG_MAX_SERDES_NUM_NW
#define SYS_TMG_MAX_MAC_NUM                          84
#define SYS_TMG_MAX_PCS_NUM_PER_DP                   SYS_TMG_MAX_SERDES_NUM_PER_DP
#define SYS_TMG_MAC_NUM_PER_TXQM                     8
#define SYS_TMG_LANE_NUM_PER_HSS                     4
#define SYS_TMG_MAX_HSS_NUM_PER_DP                   10
#define SYS_TMG_MAX_HSS_NUM                          20
#define SYS_TMG_PCS_LANE_NUM                         8
#define SYS_TMG_CHANNEL_NUM_PER_DP                   64
#define SYS_TMG_NW_CHAN_NUM_PER_DP                   52
#define SYS_TMG_LPORT_NUM_PER_DP                     SYS_TMG_CHANNEL_NUM_PER_DP
#define SYS_TMG_CHANNEL_NUM                          128
#define SYS_TMG_LPORT_NUM                            SYS_TMG_CHANNEL_NUM
#define SYS_TMG_NW_CHAN_NUM_PER_DP                   52
#define SYS_TMG_TXQM_NUM_PER_DP                      5
#define SYS_TMG_MAC_NUM_PER_MAC_GROUP                SYS_TMG_MAC_NUM_PER_TXQM
#define SYS_TMG_CPUMAC_TXQM_ID                       10
#define SYS_TMG_HSS_NUM_PER_TXQM                     2
#define SYS_TMG_CPUMAC_HSS_ID                        20
#define SYS_TMG_MAC_CLIENT_NUM_PER_DP                82
#define SYS_TMG_MAC_CLIENT_NW_NUM_PER_DP             80
#define SYS_TMG_MAC_CLIENT_NUM_PER_TXQM              16
#define SYS_TMG_CPUMAC_NUM_PER_DP                    2
#define SYS_TMG_CPUMAC_SERDSES_NUM                   4
#define SYS_TMG_EPE_PORT_PER_DP                      89

#define SYS_TMG_MAX_CAL_LEN                          512
#define SYS_TMG_NETTX_MAX_CAL_LEN_PER_TXQM           64
#define SYS_TMG_DP_BW_MAX                            1000
#define SYS_TMG_TXQM_BW_MAX_G                        200
#define SYS_TMG_TXQM_SPECIAL_BW_MAX_G                285
#define SYS_TMG_CLK_DEFAULT                          925
///TODO: need change
#define SYS_TMG_MAC_CALENDAR_MULTI_FACTOR            1000
#define SYS_TMG_MAC_CALENDAR_BUS_WIDTH_EPE           192
#define SYS_TMG_MAC_CALENDAR_BUS_WIDTH_TX            96
#define SYS_TMG_MAC_CALENDAR_CLK_MF                  925

#define SYS_TMG_MAX_QMGR_CREDIT_PER_DP               512
#define SYS_TMG_MAX_BR_SOP_CREDIT_PER_DP             1024
#define SYS_TMG_MAX_BR_BODY_CREDIT_PER_DP            768
#define SYS_TMG_MAX_BR_LOCAL_CREDIT_PER_DP           320
#define SYS_TMG_MAX_BR_REMOTE_CREDIT_PER_DP          512
#define SYS_TMG_MAX_EPE_CREDIT_PER_TXQM              256
#define SYS_TMG_MAX_NETTX_CREDIT_PER_TXQM            320
#define SYS_TMG_MISC_CHAN_ID_IN_DP                   56
#define SYS_TMG_LOOP_CHAN_ID_IN_DP                   55
#define SYS_TMG_MISC_MAC_CLIENT_IN_DP                56
#define SYS_TMG_LOOP_MAC_CLIENT_IN_DP                55

#define SYS_TMG_MCU_NUM_PER_CORE                     11
#define SYS_TMG_NETWORK_MCU_NUM_PER_CORE             10
#define SYS_TMG_CPUMAC_MCU_NUM_PER_CORE              1
#define SYS_TMG_CPUMAC_MCU_ID                        10

#define SYS_TMG_GET_HSS_ID_BY_SERDES(serdes_id)      ((serdes_id) / SYS_TMG_LANE_NUM_PER_HSS)
#define SYS_TMG_GET_INNER_LANE_BY_SERDES(serdes_id)  ((serdes_id) % SYS_TMG_LANE_NUM_PER_HSS)
#define SYS_TMG_GET_MAC_ID_BY_IDX(mac_group_id, mac_idx) ((mac_group_id) * SYS_TMG_MAC_NUM_PER_MAC_GROUP + (mac_idx))

#define SYS_TMG_ALLOC_MAC_STEP 1            
#define SYS_TMG_IS_MODE_VALID(mode)  ((CTC_CHIP_SERDES_NONE_MODE == mode) || (CTC_CHIP_SERDES_XFI_MODE == mode) || \
                                         (CTC_CHIP_SERDES_SGMII_MODE == mode) || (CTC_CHIP_SERDES_2DOT5G_MODE == mode) || \
                                         (CTC_CHIP_SERDES_XLG_MODE == mode) || (CTC_CHIP_SERDES_LG_MODE == mode) || \
                                         (CTC_CHIP_SERDES_XXVG_MODE == mode) || (CTC_CHIP_SERDES_CG_MODE == mode))
#define SYS_TMG_IS_NW_SERDES(serdes_id) ((serdes_id < SYS_TMG_MAX_SERDES_NUM_NW) ? TRUE : FALSE)
#define SYS_TMG_IS_CPUMAC_NW_SERDES(serdes_id) (((serdes_id >= SYS_TMG_MAX_SERDES_NUM_NW) && (serdes_id < SYS_TMG_MAX_SERDES_NUM_NW + 4)) ? TRUE : FALSE)
#define SYS_TMG_GET_NETTX_CREDIT_FROM_SPEED(speed) ((speed)>=100) ? 28 : (((speed)>=40) ? 14 : (((speed)>=25) ? 7 : (((speed)>=1) ? 7 : 0)))
#define SYS_TMG_IS_NW_CHAN(sub_chan) ((sub_chan < SYS_TMG_NW_CHAN_NUM_PER_DP) ? TRUE : FALSE)

#define SYS_TMG_GET_LANE_NUM_BY_MODE(mode, lane_num) \
do {\
    switch(mode)\
    {\
        case CTC_CHIP_SERDES_LG_MODE:\
        case CTC_CHIP_SERDES_XLG_R2_MODE:\
            lane_num = 2;\
            break;\
        case CTC_CHIP_SERDES_XLG_MODE:\
        case CTC_CHIP_SERDES_CG_MODE:\
            lane_num = 4;\
            break;\
        case CTC_CHIP_SERDES_XFI_MODE:\
        case CTC_CHIP_SERDES_SGMII_MODE:\
        case CTC_CHIP_SERDES_2DOT5G_MODE:\
        case CTC_CHIP_SERDES_XXVG_MODE:\
            lane_num = 1;\
            break;\
        default:\
            lane_num = 0;\
            break;\
    }\
} while(0)

#define SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan_id, dp_id) ((dp_chan_id) + (dp_id)*SYS_TMG_CHANNEL_NUM_PER_DP)
#define SYS_TMG_CHANNEL_TO_DPCHAN(chan_id) ((chan_id) % (SYS_TMG_CHANNEL_NUM_PER_DP))
#define SYS_TMG_GET_DP_ID_FROM_CHANID(chan_id) ((chan_id) / SYS_TMG_CHANNEL_NUM_PER_DP)
#define SYS_TMG_CHANNEL_TO_256CHAN(chan_id) (((chan_id) < SYS_TMG_CHANNEL_NUM_PER_DP) ? (chan_id) : ((chan_id) + 64))

#define SYS_TMG_IS_MISC_CHAN(dp, dp_chan) (((52 <= (dp_chan)) && (63 >= (dp_chan))) || \
                                           (MCHIP_CAP(SYS_CAP_CHANID_DROP) == SYS_TMG_GET_DPCHAN_TO_CHANNEL(dp_chan, dp)))
    

#define SYS_TMG_GET_PORT_NUM_BY_MODE(mode, port_num) \
    do {\
        switch(mode)\
        {\
            case CTC_CHIP_SERDES_XFI_MODE:\
            case CTC_CHIP_SERDES_SGMII_MODE:\
            case CTC_CHIP_SERDES_2DOT5G_MODE:\
            case CTC_CHIP_SERDES_XXVG_MODE:\
            case CTC_CHIP_SERDES_LG_MODE:\
            case CTC_CHIP_SERDES_XLG_MODE:\
            case CTC_CHIP_SERDES_CG_MODE:\
                port_num = 1;\
                break;\
            default:\
                port_num = 0;\
                break;\
        }\
    } while(0)


#define SYS_TMG_GET_PORT_IFTYPE(mode, iftype) do { \
    switch(mode)                               \
    {                                          \
        case CTC_CHIP_SERDES_SGMII_MODE:       \
            iftype = CTC_PORT_IF_SGMII;        \
            break;                             \
        case CTC_CHIP_SERDES_XFI_MODE:         \
            iftype = CTC_PORT_IF_XFI;          \
            break;                             \
        case CTC_CHIP_SERDES_2DOT5G_MODE:      \
            iftype = CTC_PORT_IF_2500X;        \
            break;                             \
        case CTC_CHIP_SERDES_XXVG_MODE:        \
            iftype = CTC_PORT_IF_CR;           \
            break;                             \
        case CTC_CHIP_SERDES_LG_MODE:          \
            iftype = CTC_PORT_IF_CR2;          \
            break;                             \
        case CTC_CHIP_SERDES_CG_MODE:          \
            iftype = CTC_PORT_IF_CR4;          \
            break;                             \
        case CTC_CHIP_SERDES_XLG_MODE:         \
            iftype = CTC_PORT_IF_CR4;          \
            break;                             \
        default:                               \
            iftype = CTC_PORT_IF_MAX_TYPE;     \
            break;                             \
        }                                      \
} while(0)

struct sys_tmg_nettx_cal_heap_s
{
    uint32 portid_order[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM];/*interval,per port*/
    uint32 num[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM];/*select num ,per port*/
    uint32 first_cal_record[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM];/*record the index first select*/
    uint32 cnt_history[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM];
    uint32 expect_margine[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM+1];
};
typedef struct sys_tmg_nettx_cal_heap_s sys_tmg_nettx_cal_heap_t;

struct sys_tmg_dmps_id_dictionary_s
{
    uint8  pp_id;
    uint8  dp_id;
    uint8  txqm_id;
    uint16 mac_client;
};
typedef struct sys_tmg_dmps_id_dictionary_s sys_tmg_dmps_id_dictionary_s;

#define TMG_MAX_XPIPE_CHAN 2


/****************************************************************************
 *
* Function
*
*****************************************************************************/
extern int32 sys_tmg_datapath_init(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg);
extern int32 _sys_tmg_check_datapath_credit_clear(uint8 lchip, uint32 mac_id, uint32 chan_id);

#ifdef __cplusplus
}
#endif

#endif

